
package io.dbw.modules.business.controller.sys;

import com.alibaba.fastjson.JSONObject;
import io.dbw.common.annotation.SysLog;
import io.dbw.common.enums.BusinessTypeEnum;
import io.dbw.common.enums.ResultStatusEnum;
import io.dbw.common.utils.*;
import io.dbw.modules.business.entity.SysUserEntity;
import io.dbw.modules.business.entity.SysVerificationCodeEntity;
import io.dbw.modules.business.form.StoreLoginForm;
import io.dbw.modules.business.form.SysLoginForm;
import io.dbw.modules.business.oauth2.TokenGenerator;
import io.dbw.modules.business.service.SysCaptchaService;
import io.dbw.modules.business.service.SysUserService;
import io.dbw.modules.business.service.SysUserTokenService;
import io.dbw.modules.business.service.SysVerificationCodeService;
import io.dbw.modules.business.vo.CaptchaVO;
import io.dbw.modules.business.vo.LoginUserVO;
import io.dbw.modules.business.vo.SysVerificationCodeVO;
import io.dbw.modules.utils.weixin.WeiXinUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
import java.util.Date;
import java.util.Map;

/**
 * 登录相关
 *
 * 
 */
@Slf4j
@Validated
@RestController
@Api(tags = "登录管理")
public class SysLoginController extends AbstractController {
	@Autowired
	private SysUserService sysUserService;
	@Autowired
	private SysUserTokenService sysUserTokenService;
	@Autowired
	private SysCaptchaService sysCaptchaService;
	@Autowired
	private SysVerificationCodeService sysVerificationCodeService;
	@Resource
	private ThreadPoolTaskExecutor threadPoolTaskExecutor;

	@Value("${spring.profiles.active}")
	private String active;
	@Autowired
	private static String EXECUTE_DATE=null;
	/**
	 * 验证码
	 */
	@GetMapping("captcha.jpg")
	@ApiOperation(value="获取验证码")
	public Result<CaptchaVO> captcha() {
		String uuid= TokenGenerator.generateValue();
		//获取图片验证码
		CaptchaVO captchaVO=new CaptchaVO();
		captchaVO.setUuid(uuid);
		captchaVO.setImgBase("data:image/jpg;base64,"+FileUtils.getCaptcha(sysCaptchaService.getCaptcha(uuid)));
		return writeSuccess(captchaVO);
	}
	/**
	 * 退出
	 */
	@PostMapping("/sys/logout")
	@ApiOperation(value="登出")
	@SysLog(value = "登出",businessType = BusinessTypeEnum.LOGOUT,isSaveRequestData = false)
	public Result logout(HttpServletRequest httpServletRequest) {
		String token = httpServletRequest.getHeader("token");
		if(StringUtils.isNotBlank(token)){
			sysUserTokenService.logout(token);
			SecurityUtils.getSubject().logout();
		}
		return writeSuccess();
	}


	/*学生 platform
	买家 purchase
	商家 supply*/
	/**
	 * 系统用户账号登录
	 */
	@PostMapping("/sysLogin")
	@ApiOperation(value="学生登录")
	@SysLog(value = "学生登录",businessType = BusinessTypeEnum.LOGIN)
	public Result<LoginUserVO> login(@RequestBody  @Validated SysLoginForm form)  throws Exception {
		return sysUserService.login(form);
	}



	/**
	 * 公司登录
	 */
	@ApiIgnore
	@PostMapping("/mobileLogin")
	@ApiOperation(value="手机号登录")
	@SysLog(value = "公司登录",businessType = BusinessTypeEnum.LOGIN)
	public Result<LoginUserVO> mobileLogin(@RequestBody  @Validated StoreLoginForm form)  throws Exception {
		return sysUserService.mobileLogin(form);
	}


	/**
	 * 微信扫码登录
	 */
	@ApiIgnore
	@PostMapping("/weChatLogin")
	@ApiOperation(value="微信扫码登录")
	public Result<LoginUserVO> weChatLogin(@RequestBody Map<String,String> param)  throws Exception {
		String code = MapUtils.getString(param, "code");
		if(StringUtils.isBlank(code)){
			return Result.error("code不能为空");
		}
		JSONObject json = WeiXinUtil.getAccessToken(code);
		if(null==json || StringUtils.isBlank(json.getString("access_token"))){
			if(40029==json.getInteger("errcode")){
				return Result.error("二维码已过期,请刷新重新登录");
			}
			return Result.error("扫码登录失败,请刷新重新登录");
		}
		SysLoginForm form=new SysLoginForm();
		form.setUserName("qudao001");
		form.setPassword("tD6fAyAtN5iJGpuwlb8L8lhK3ajwwmCFLtncF+I1Utg=");
		return sysUserService.login(form);
	}



	/**
	 　* @description: 发送手机验证码
	 　* @param phone
	 　* @return
	 　* @author lxc
	 　* @date 2021/9/30 10:25
	 */
	@GetMapping("/getPhoneByUserName")
	@ApiOperation(value="通过用户名获取手机号")
	@ApiImplicitParam(paramType = "query",name = "userName",value ="用户名",dataType ="String",required = true)
	@SysLog(value = "通过用户名获取手机号",businessType = BusinessTypeEnum.LOGIN)
	public Result<String> getPhoneByUserName(@NotBlank(message = "用户名不能为空!") String userName) throws Exception {
		String phone = null;
		try {
			SysUserEntity userEntity = sysUserService.queryByUserName(userName);
			//账号不存在
			if(userEntity == null ) {
				return writeFail(ResultStatusEnum.USER_ERROR.getMsg());
			}
			//账号锁定
			if(userEntity.getStatus() == 0){
				return writeFail(ResultStatusEnum.USER_FROZEN.getMsg());
			}
			String mobile = userEntity.getMobile();
			phone = mobile.substring(mobile.length()-4);
		}catch (Exception e) {
			log.info("--getPhoneByUserName.error-->:" + e);
			return writeError("用户手机号异常，请联系管理员！");
		}
		return writeSuccess(phone);
	}

	/**
	 　* @description: 发送手机验证码
	 　* @param phone
	 　* @return
	 　* @author lxc
	 　* @date 2021/9/30 10:25
	 */
	@GetMapping("/sendPhoneCode")
	@ApiOperation(value="发送手机验证码")
	@ApiImplicitParam(paramType = "query",name = "userName",value ="用户名",dataType ="String",required = true)
	@SysLog(value = "发送验证码",businessType = BusinessTypeEnum.LOGIN)
	public Result sendPhoneCode(@NotBlank(message = "用户名不能为空!") String userName) throws Exception {

		try {
			SysUserEntity userEntity = sysUserService.queryByUserName(userName);
			String phone = userEntity.getMobile();
			String code = StringUtil.getRandom();
			log.info("--sendPhoneCode-->phone:" + phone + ",code:" + code);
			SysVerificationCodeVO codeVO = sysVerificationCodeService.getCodeInfoByPhone(phone);
			if (codeVO != null) {
				Integer num = codeVO.getNum();
				if (num >= 3) {
					return writeFail("本手机号今日已超过限制次数,不能再获取验证码!");
				}
				Date time = codeVO.getCreateTime();
				//计算还相差了多少秒
				if ((DateUtils.diffTime(time) / 1000) < 60) {
					//放入time 发送的上一回和现在差了多少秒
					return writeFail("您的操作太频繁,请稍后再试!");
				}
			}
			threadPoolTaskExecutor.execute(new Runnable() {
				@Override
				public void run() {
					//发送验证码逻辑
					//SampleUtil.smsSend(phone, code);
				}
			});
			SysVerificationCodeEntity codeEntity = new SysVerificationCodeEntity();
			codeEntity.setPhone(phone);
			codeEntity.setCode(code);
			codeEntity.setCreateBy(userEntity.getUserId());
			sysVerificationCodeService.save(codeEntity);
		}catch (Exception e) {
			log.info("--sendPhoneCode.error-->:" + e);
			return writeError("手机发送验证码异常，请联系管理员！");
		}
		return writeSuccess();
	}


	@PostMapping("/resetNewPassword")
	@ApiOperation(value="重置新密码")
	@SysLog(value = "用户",businessType = BusinessTypeEnum.PASSWORD_UPDATE)
	public Result resetNewPassword(@RequestBody SysVerificationCodeVO codeVO){
		AssertUtils.isNull(codeVO.getUserName(),"用户名不能为空!");
		AssertUtils.isNull(codeVO.getCode(),"验证码不能为空!");
		AssertUtils.isNull(codeVO.getNewPassword(),"新密码不能为空!");
		try {
			SysUserEntity userEntity = sysUserService.queryByUserName(codeVO.getUserName());
			//账号不存在
			if(userEntity == null ) {
				return writeFail(ResultStatusEnum.USER_ERROR.getMsg());
			}
			//账号锁定
			if(userEntity.getStatus() == 0){
				return writeFail(ResultStatusEnum.USER_FROZEN.getMsg());
			}
			SysVerificationCodeVO verificationCodeVO = sysVerificationCodeService.getCodeInfoByPhone(userEntity.getMobile());
			if (verificationCodeVO == null) {
				return writeFail("验证码查询为空，请检查用户名是否正确！");
			}
			if (!codeVO.getCode().equals(verificationCodeVO.getCode())) {
				return writeFail(ResultStatusEnum.INVALID_CAPTCHA_ERROR.getMsg());
			}
			Date time = verificationCodeVO.getCreateTime();
			//计算还相差了多少秒-验证码不超过三分钟
			if ((DateUtils.diffTime(time) / 1000) > 3*60) {
				//放入time 发送的上一回和现在差了多少秒
				return writeFail("验证码已失效,请重新发送!");
			}
			sysUserService.updatePassword(userEntity.getUserId(),codeVO.getNewPassword());
		}catch (Exception e) {
			return writeError("重置新密码异常，请联系管理员！");
		}
		return writeSuccess();
	}

}
